package org.cy.spring.learning.rpc.server;

import org.cy.spring.learning.rpc.comm.network.Request;
import org.cy.spring.learning.rpc.comm.network.Response;
import org.cy.spring.learning.rpc.discover.LocalDefaultServiceRegistry;
import org.cy.spring.learning.rpc.discover.ServiceDefinition;
import org.cy.spring.learning.rpc.discover.ServiceRegistry;
import org.cy.spring.learning.rpc.provider.PersonService;
import org.cy.spring.learning.rpc.provider.PersonServiceImpl;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * create date: 2019/10/23 10:57
 *
 * @author cao.yong
 */
public class SocketServer implements ContainerServer {

    private boolean start = true;
    private ServerSocket serverSocket;

    private ServiceRegistry registry;

    private void setRegistry(ServiceRegistry registry) {
        this.registry = registry;
    }

    @Override
    public void start() {
        try {
            serverSocket = new ServerSocket(8888);
            while (start) {
                // 接收客户端链接
                Socket socket = serverSocket.accept();
                // 接收请求对象
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                Request request = (Request) ois.readObject();
                // 获取注册中心的服务
                ServiceDefinition service = registry.getService(request.getServiceName());
                // 执行服务方法
                Method method = service.getInstance().getClass().getMethod(request.getMethodName(), request.getParameterTypes());
                Object result = method.invoke(service.getInstance(), request.getParameters());

                // 组装响应对象
                Response response = new Response();
                response.setId(request.getId());
                response.setCode(0);
                response.setMsg("success");
                response.setData(result);

                // 返回响应
                ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                oos.writeObject(response);
                oos.flush();

                // 关闭流
                oos.close();
                ois.close();

                socket.close();
            }
        } catch (IOException | ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void stop() {
        try {
            start = false;
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException {
        ServiceRegistry serviceRegistry = new LocalDefaultServiceRegistry();
        serviceRegistry.register(PersonService.class.getName(), new PersonServiceImpl());

        SocketServer server = new SocketServer();
        server.setRegistry(serviceRegistry);
        server.start();
        int read = System.in.read();
        if (read > -1) {
            server.stop();
        }
    }
}
